package com.fudan.es.aggs.handler.base;

import java.util.List;
import java.util.Map;

import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.beans.factory.annotation.Autowired;

import com.fudan.es.aggs.ConstString;
import com.fudan.es.aggs.ResponseParser;
import com.fudan.es.aggs.handler.AvgHandler;
import com.fudan.es.aggs.handler.DateHandler;
import com.fudan.es.aggs.handler.SumHandler;
import com.fudan.es.aggs.handler.TermsHandler;
import com.fudan.es.aggs.DimensionParser.DimensionType;
import com.fudan.es.aggs.request.handler.dimension.DimensionHandler;
import com.fudan.es.entity.DimensionPack;
import com.fudan.es.entity.FieldMeta;
import com.fudan.es.entity.MetricPack;
import com.fudan.es.entity.MetricPack.MetricType;
import com.fudan.framework.utils.SpringUtils;

public abstract class AggsHandler {
	protected final static String NO_FIELD = "没有指定聚合字段";
	protected final static String FIELD_NOT_AGGREGATABLE = "指定字段不支持聚合";

	protected final static String MISSING = "Missing";
	protected static final String ROOT_PATH = ConstString.ROOT_PATH;
	protected static final String DEFAULT_DOC = ConstString.DEFAULT_DOC;

	protected static final String SUM_TAG = ConstString.SUM_TAG;
	protected static final String AVG_TAG = ConstString.AVG_TAG;
	protected static final String TERMS_TAG = ConstString.TERMS_TAG;

	@Autowired
	protected ResponseParser responseParser;

	protected String getAggregationName(MetricPack metricPack) {
		return metricPack.getType().toString()+"$"+metricPack.getField().getId();
	}

	abstract public AggregationBuilder handle(DimensionPack dimension);
	abstract public AggregationBuilder build(MetricPack metric);
	abstract public Map<String,Object> handle(Map<String,Object> map,Aggregations aggregations,MetricPack metricPack);
	public void handle(MetricPack root,MetricPack metric) {
		FieldMeta field = metric.getField();
		if(field == null) {
			throw new RuntimeException(NO_FIELD);
		}
		if(!field.getAggregatable()) {
			throw new RuntimeException(FIELD_NOT_AGGREGATABLE);
		}
		List<MetricPack> metricList = metric.getMetric();
		if(metricList != null) {
			for (MetricPack metricPack : metricList) {
				handle(metric,metricPack);
			}
		}
		if(root != null) {
			root.add(metric);
		}
	}

	public static AggsHandler buildHandler(DimensionType type) {
		switch (type) {
		case TERMS:
			return get(TermsHandler.class);
		case DATE:
			return get(DateHandler.class);
		default:
			return null;
		}
	}
	public static AggsHandler buildHandler(MetricType type) {
		switch (type) {
		case TERMS:
			return get(TermsHandler.class);
		case AVG:
			return get(AvgHandler.class);
		case SUM:
			return get(SumHandler.class);
		case DATE:
			return get(DateHandler.class);
		default:
			return null;
		}
	}

	private static <T> T get(Class<T> clz) {
		return SpringUtils.getBean(clz);
	}
}
